home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / osmesa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  35.5 KB  |  1,284 lines

  1. /* $Id: osmesa.c,v 1.10 1997/03/06 01:10:29 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: osmesa.c,v $
  26.  * Revision 1.10  1997/03/06 01:10:29  brianp
  27.  * added Randy Frank's optimized line drawing code
  28.  *
  29.  * Revision 1.9  1997/02/10 20:34:33  brianp
  30.  * added OSMESA_RGB and OSMESA_BGR, per Randy Frank
  31.  *
  32.  * Revision 1.8  1996/10/25 00:09:45  brianp
  33.  * pass DEPTH_BITS, STENCIL_BITS, and ACCUM_BITS to gl_create_visual()
  34.  *
  35.  * Revision 1.7  1996/10/01 03:30:48  brianp
  36.  * use new FixedToDepth() macro
  37.  *
  38.  * Revision 1.6  1996/10/01 01:43:21  brianp
  39.  * added extra braces to the INNER_LOOP triangle macros
  40.  *
  41.  * Revision 1.5  1996/09/27 01:32:37  brianp
  42.  * removed unused variables
  43.  *
  44.  * Revision 1.4  1996/09/19 03:17:28  brianp
  45.  * now just one parameter to gl_create_framebuffer()
  46.  *
  47.  * Revision 1.3  1996/09/15 14:28:16  brianp
  48.  * now use GLframebuffer and GLvisual
  49.  *
  50.  * Revision 1.2  1996/09/14 20:20:11  brianp
  51.  * misc bug fixes from Randy Frank
  52.  *
  53.  * Revision 1.1  1996/09/13 01:38:16  brianp
  54.  * Initial revision
  55.  *
  56.  */
  57.  
  58.  
  59.  
  60. /*
  61.  * Off-Screen Mesa rendering / Rendering into client memory space
  62.  */
  63.  
  64.  
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include "GL/osmesa.h"
  68. #include "context.h"
  69. #include "depth.h"
  70. #include "macros.h"
  71. #include "matrix.h"
  72. #include "types.h"
  73. #include "vb.h"
  74. #include "bresenhm.h"
  75.  
  76.  
  77. struct osmesa_context {
  78.    GLcontext *gl_ctx;        /* The core GL/Mesa context */
  79.    GLvisual *gl_visual;        /* Describes the buffers */
  80.    GLframebuffer *gl_buffer;    /* Depth, stencil, accum, etc buffers */
  81.    GLenum format;        /* either GL_RGBA or GL_COLOR_INDEX */
  82.    void *buffer;        /* the image buffer */
  83.    GLint width, height;        /* size of image buffer */
  84.    GLuint pixel;        /* current color index or RGBA pixel value */
  85.    GLuint clearpixel;        /* pixel for clearing the color buffer */
  86.    GLint rowlength;        /* number of pixels per row */
  87.    GLint rshift, gshift;    /* bit shifts for RGBA formats */
  88.    GLint bshift, ashift;
  89.    GLint rind, gind, bind;    /* index offsets for RGBA formats */
  90.    void *rowaddr[MAX_HEIGHT];    /* address of first pixel in each image row */
  91.    GLboolean yup;        /* TRUE  -> Y increases upward */
  92.                 /* FALSE -> Y increases downward */
  93. };
  94.  
  95.  
  96.  
  97. #ifdef THREADS
  98.    /* A context handle for each thread */
  99.    /* TODO: an array/table of contexts indexed by thread IDs */
  100. #else
  101.    /* One current context for address space, all threads */
  102.    static OSMesaContext Current = NULL;
  103. #endif
  104.  
  105.  
  106.  
  107. /* A forward declaration: */
  108. static void osmesa_setup_DD_pointers( GLcontext *ctx );
  109.  
  110.  
  111.  
  112.  
  113. /*
  114.  * Create an Off-Screen Mesa rendering context.  The only attribute needed is
  115.  * an RGBA vs Color-Index mode flag.
  116.  *
  117.  * Input:  format - either GL_RGBA or GL_COLOR_INDEX
  118.  *         sharelist - specifies another OSMesaContext with which to share
  119.  *                     display lists.  NULL indicates no sharing.
  120.  * Return:  an OSMesaContext or 0 if error
  121.  */
  122. OSMesaContext OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
  123. {
  124.    OSMesaContext osmesa;
  125.    GLfloat rscale, gscale, bscale, ascale;
  126.    GLint rshift, gshift, bshift, ashift;
  127.    GLint rind, gind, bind;
  128.    GLint index_bits;
  129.    GLboolean rgbmode;
  130.    GLboolean swalpha;
  131.    GLuint i4 = 1;
  132.    GLubyte *i1 = (GLubyte *) &i4;
  133.    GLint little_endian = *i1;
  134.  
  135.    swalpha = GL_FALSE;
  136.    rind = gind = bind = 0;
  137.    if (format==OSMESA_COLOR_INDEX) {
  138.       rscale = gscale = bscale = ascale = 0.0;
  139.       index_bits = 8;
  140.       rshift = gshift = bshift = ashift = 0;
  141.       rgbmode = GL_FALSE;
  142.    }
  143.    else if (format==OSMESA_RGBA) {
  144.       rscale = gscale = bscale = ascale = 255.0;
  145.       index_bits = 0;
  146.       if (little_endian) {
  147.          rshift = 0;
  148.          gshift = 8;
  149.          bshift = 16;
  150.          ashift = 24;
  151.       }
  152.       else {
  153.          rshift = 24;
  154.          gshift = 16;
  155.          bshift = 8;
  156.          ashift = 0;
  157.       }
  158.       rgbmode = GL_TRUE;
  159.    }
  160.    else if (format==OSMESA_BGRA) {
  161.       rscale = gscale = bscale = ascale = 255.0;
  162.       index_bits = 0;
  163.       if (little_endian) {
  164.          ashift = 0;
  165.          rshift = 8;
  166.          gshift = 16;
  167.          bshift = 24;
  168.       }
  169.       else {
  170.          bshift = 24;
  171.          gshift = 16;
  172.          rshift = 8;
  173.          ashift = 0;
  174.       }
  175.       rgbmode = GL_TRUE;
  176.    }
  177.    else if (format==OSMESA_ARGB) {
  178.       rscale = gscale = bscale = ascale = 255.0;
  179.       index_bits = 0;
  180.       if (little_endian) {
  181.          bshift = 0;
  182.          gshift = 8;
  183.          rshift = 16;
  184.          ashift = 24;
  185.       }
  186.       else {
  187.          ashift = 24;
  188.          rshift = 16;
  189.          gshift = 8;
  190.          bshift = 0;
  191.       }
  192.       rgbmode = GL_TRUE;
  193.    }
  194.    else if (format==OSMESA_RGB) {
  195.       rscale = gscale = bscale = ascale = 255.0;
  196.       index_bits = 0;
  197.       bshift = 0;
  198.       gshift = 8;
  199.       rshift = 16;
  200.       ashift = 24;
  201.       bind = 2;
  202.       gind = 1;
  203.       rind = 0;
  204.       rgbmode = GL_TRUE;
  205.       swalpha = GL_TRUE;
  206.    }
  207.    else if (format==OSMESA_BGR) {
  208.       rscale = gscale = bscale = ascale = 255.0;
  209.       index_bits = 0;
  210.       bshift = 0;
  211.       gshift = 8;
  212.       rshift = 16;
  213.       ashift = 24;
  214.       bind = 0;
  215.       gind = 1;
  216.       rind = 2;
  217.       rgbmode = GL_TRUE;
  218.       swalpha = GL_TRUE;
  219.    }
  220.    else {
  221.       return NULL;
  222.    }
  223.  
  224.  
  225.    osmesa = (OSMesaContext) calloc( 1, sizeof(struct osmesa_context) );
  226.    if (osmesa) {
  227.       osmesa->gl_visual = gl_create_visual( rgbmode,
  228.                         swalpha,    /* software alpha */
  229.                                             GL_FALSE,    /* db_flag */
  230.                                             DEPTH_BITS,
  231.                                             STENCIL_BITS,
  232.                                             ACCUM_BITS,
  233.                                             index_bits,
  234.                                             rscale, gscale, bscale, ascale );
  235.       if (!osmesa->gl_visual) {
  236.          return NULL;
  237.       }
  238.  
  239.       osmesa->gl_ctx = gl_create_context( osmesa->gl_visual,
  240.                                           sharelist ? sharelist->gl_ctx : NULL,
  241.                                           (void *) osmesa );
  242.       if (!osmesa->gl_ctx) {
  243.          gl_destroy_visual( osmesa->gl_visual );
  244.          free(osmesa);
  245.          return NULL;
  246.       }
  247.       osmesa->gl_buffer = gl_create_framebuffer( osmesa->gl_visual );
  248.       if (!osmesa->gl_buffer) {
  249.          gl_destroy_visual( osmesa->gl_visual );
  250.          gl_destroy_context( osmesa->gl_ctx );
  251.          free(osmesa);
  252.          return NULL;
  253.       }
  254.       osmesa->format = format;
  255.       osmesa->buffer = NULL;
  256.       osmesa->width = 0;
  257.       osmesa->height = 0;
  258.       osmesa->pixel = 0;
  259.       osmesa->clearpixel = 0;
  260.       osmesa->rowlength = 0;
  261.       osmesa->yup = GL_TRUE;
  262.       osmesa->rshift = rshift;
  263.       osmesa->gshift = gshift;
  264.       osmesa->bshift = bshift;
  265.       osmesa->ashift = ashift;
  266.       osmesa->rind = rind;
  267.       osmesa->gind = gind;
  268.       osmesa->bind = bind;
  269.    }
  270.    return osmesa;
  271. }
  272.  
  273.  
  274.  
  275. /*
  276.  * Destroy an Off-Screen Mesa rendering context.
  277.  *
  278.  * Input:  ctx - the context to destroy
  279.  */
  280. void OSMesaDestroyContext( OSMesaContext ctx )
  281. {
  282.    if (ctx) {
  283.       gl_destroy_visual( ctx->gl_visual );
  284.       gl_destroy_framebuffer( ctx->gl_buffer );
  285.       gl_destroy_context( ctx->gl_ctx );
  286.       free( ctx );
  287.    }
  288. }
  289.  
  290.  
  291.  
  292. /*
  293.  * Recompute the values of the context's rowaddr array.
  294.  */
  295. static void compute_row_addresses( OSMesaContext ctx )
  296. {
  297.    GLint i;
  298.  
  299.    if (ctx->yup) {
  300.       /* Y=0 is bottom line of window */
  301.       if (ctx->format==OSMESA_COLOR_INDEX) {
  302.          /* 1-byte CI mode */
  303.          GLubyte *origin = (GLubyte *) ctx->buffer;
  304.          for (i=0;i<MAX_HEIGHT;i++) {
  305.             ctx->rowaddr[i] = origin + i * ctx->rowlength;
  306.          }
  307.       }
  308.       else {
  309.          if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
  310.             /* 3-byte RGB mode */
  311.             GLubyte *origin = (GLubyte *) ctx->buffer;
  312.             for (i=0;i<MAX_HEIGHT;i++) {
  313.                ctx->rowaddr[i] = origin + (i * (ctx->rowlength*3));
  314.             }
  315.          } else {
  316.             /* 4-byte RGBA mode */
  317.             GLuint *origin = (GLuint *) ctx->buffer;
  318.             for (i=0;i<MAX_HEIGHT;i++) {
  319.                ctx->rowaddr[i] = origin + i * ctx->rowlength;
  320.             }
  321.          }
  322.       }
  323.    }
  324.    else {
  325.       /* Y=0 is top line of window */
  326.       if (ctx->format==OSMESA_COLOR_INDEX) {
  327.          /* 1-byte CI mode */
  328.          GLubyte *origin = (GLubyte *) ctx->buffer;
  329.          for (i=0;i<MAX_HEIGHT;i++) {
  330.             ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
  331.          }
  332.       }
  333.       else {
  334.          if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
  335.             /* 3-byte RGB mode */
  336.             GLubyte *origin = (GLubyte *) ctx->buffer;
  337.             for (i=0;i<MAX_HEIGHT;i++) {
  338.                ctx->rowaddr[i] = origin + ((ctx->height-i-1) * (ctx->rowlength*3));
  339.             }
  340.          } else {
  341.             /* 4-byte RGBA mode */
  342.             GLuint *origin = (GLuint *) ctx->buffer;
  343.             for (i=0;i<MAX_HEIGHT;i++) {
  344.                ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
  345.             }
  346.          }
  347.       }
  348.    }
  349. }
  350.  
  351.  
  352. /*
  353.  * Bind an OSMesaContext to an image buffer.  The image buffer is just a
  354.  * block of memory which the client provides.  Its size must be at least
  355.  * as large as width*height*sizeof(type).  Its address should be a multiple
  356.  * of 4 if using RGBA mode.
  357.  *
  358.  * Image data is stored in the order of glDrawPixels:  row-major order
  359.  * with the lower-left image pixel stored in the first array position
  360.  * (ie. bottom-to-top).
  361.  *
  362.  * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
  363.  * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
  364.  * value.  If the context is in color indexed mode, each pixel will be
  365.  * stored as a 1-byte value.
  366.  *
  367.  * If the context's viewport hasn't been initialized yet, it will now be
  368.  * initialized to (0,0,width,height).
  369.  *
  370.  * Input:  ctx - the rendering context
  371.  *         buffer - the image buffer memory
  372.  *         type - data type for pixel components, only GL_UNSIGNED_BYTE
  373.  *                supported now
  374.  *         width, height - size of image buffer in pixels, at least 1
  375.  * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
  376.  *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
  377.  *          width>internal limit or height>internal limit.
  378.  */
  379. GLboolean OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
  380.                              GLsizei width, GLsizei height )
  381. {
  382.    if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
  383.        || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
  384.       return GL_FALSE;
  385.    }
  386.  
  387.    gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
  388.  
  389.    ctx->buffer = buffer;
  390.    ctx->width = width;
  391.    ctx->height = height;
  392.    if (ctx->rowlength==0) {
  393.       ctx->rowlength = width;
  394.    }
  395.  
  396.    osmesa_setup_DD_pointers( ctx->gl_ctx );
  397.  
  398. #ifdef THREADS
  399.    /* Set current context for the calling thread */
  400.    /* TODO */
  401. #else
  402.    /* Set current context for the address space, all threads */
  403.    Current = ctx;
  404. #endif
  405.  
  406.    compute_row_addresses( ctx );
  407.  
  408.    /* init viewport */
  409.    if (ctx->gl_ctx->Viewport.Width==0) {
  410.       /* initialize viewport and scissor box to buffer size */
  411.       gl_Viewport( ctx->gl_ctx, 0, 0, width, height );
  412.       ctx->gl_ctx->Scissor.Width = width;
  413.       ctx->gl_ctx->Scissor.Height = height;
  414.    }
  415.  
  416.    return GL_TRUE;
  417. }
  418.  
  419.  
  420.  
  421.  
  422. OSMesaContext OSMesaGetCurrentContext( void )
  423. {
  424. #ifdef THREADS
  425.    /* Return current handle for the calling thread */
  426. #else
  427.    /* Return current handle for the address space, all threads */
  428.    return Current;
  429. #endif
  430. }
  431.  
  432.  
  433.  
  434. void OSMesaPixelStore( GLint pname, GLint value )
  435. {
  436.    OSMesaContext ctx = OSMesaGetCurrentContext();
  437.  
  438.    switch (pname) {
  439.       case OSMESA_ROW_LENGTH:
  440.          if (value<0) {
  441.             gl_error( ctx->gl_ctx, GL_INVALID_VALUE,
  442.                       "OSMesaPixelStore(value)" );
  443.             return;
  444.          }
  445.          ctx->rowlength = value;
  446.          break;
  447.       case OSMESA_Y_UP:
  448.          ctx->yup = value ? GL_TRUE : GL_FALSE;
  449.          break;
  450.       default:
  451.          gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
  452.          return;
  453.    }
  454.  
  455.    compute_row_addresses( ctx );
  456. }
  457.  
  458.  
  459. void OSMesaGetIntegerv( GLint pname, GLint *value )
  460. {
  461.    OSMesaContext ctx = OSMesaGetCurrentContext();
  462.  
  463.    switch (pname) {
  464.       case OSMESA_WIDTH:
  465.          *value = ctx->width;
  466.          return;
  467.       case OSMESA_HEIGHT:
  468.          *value = ctx->height;
  469.          return;
  470.       case OSMESA_FORMAT:
  471.          *value = ctx->format;
  472.          return;
  473.       case OSMESA_TYPE:
  474.          *value = GL_UNSIGNED_BYTE;
  475.          return;
  476.       case OSMESA_ROW_LENGTH:
  477.          *value = ctx->rowlength;
  478.          return;
  479.       case OSMESA_Y_UP:
  480.          *value = ctx->yup;
  481.          return;
  482.       default:
  483.          gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)" );
  484.          return;
  485.    }
  486. }
  487.  
  488.  
  489.  
  490. /**********************************************************************/
  491. /*** Device Driver Functions                                        ***/
  492. /**********************************************************************/
  493.  
  494.  
  495. /*
  496.  * Useful macros:
  497.  */
  498. #define PACK_RGBA(R,G,B,A)  (  ((R) << osmesa->rshift) \
  499.                              | ((G) << osmesa->gshift) \
  500.                              | ((B) << osmesa->bshift) \
  501.                              | ((A) << osmesa->ashift) )
  502.  
  503. #define PACK_RGBA2(R,G,B,A)  (  ((R) << rshift) \
  504.                               | ((G) << gshift) \
  505.                               | ((B) << bshift) \
  506.                               | ((A) << ashift) )
  507.  
  508. #define UNPACK_RED(P)      (((P) >> osmesa->rshift) & 0xff)
  509. #define UNPACK_GREEN(P)    (((P) >> osmesa->gshift) & 0xff)
  510. #define UNPACK_BLUE(P)     (((P) >> osmesa->bshift) & 0xff)
  511. #define UNPACK_ALPHA(P)    (((P) >> osmesa->ashift) & 0xff)
  512.  
  513. #define PIXELADDR1(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + (X))
  514. #define PIXELADDR3(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
  515. #define PIXELADDR4(X,Y)  ((GLuint *)  osmesa->rowaddr[Y] + (X))
  516.  
  517.  
  518.  
  519.  
  520. static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
  521. {
  522.    if (mode==GL_FRONT) {
  523.       return GL_TRUE;
  524.    }
  525.    else {
  526.       return GL_FALSE;
  527.    }
  528. }
  529.  
  530.  
  531. static void clear_index( GLcontext *ctx, GLuint index )
  532. {
  533.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  534.    osmesa->clearpixel = index;
  535. }
  536.  
  537.  
  538.  
  539. static void clear_color( GLcontext *ctx,
  540.                          GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  541. {
  542.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  543.    osmesa->clearpixel = PACK_RGBA( r, g, b, a );
  544. }
  545.  
  546.  
  547.  
  548. static void clear( GLcontext *ctx,
  549.                    GLboolean all, GLint x, GLint y, GLint width, GLint height )
  550. {
  551.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  552.    if (osmesa->format==OSMESA_COLOR_INDEX) {
  553.       if (all) {
  554.          /* Clear whole CI buffer */
  555.          MEMSET(osmesa->buffer, osmesa->clearpixel, osmesa->rowlength*osmesa->height);
  556.       }
  557.       else {
  558.          /* Clear part of CI buffer */
  559.          GLuint i, j;
  560.          for (i=0;i<height;i++) {
  561.             GLubyte *ptr1 = PIXELADDR1( x, (y+i) );
  562.             for (j=0;j<width;j++) {
  563.                *ptr1++ = osmesa->clearpixel;
  564.             }
  565.          }
  566.       }
  567.    }
  568.    else if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) {
  569.       GLubyte rval = UNPACK_RED(osmesa->clearpixel);
  570.       GLubyte gval = UNPACK_GREEN(osmesa->clearpixel);
  571.       GLubyte bval = UNPACK_BLUE(osmesa->clearpixel);
  572.       GLint   rind = osmesa->rind;
  573.       GLint   gind = osmesa->gind;
  574.       GLint   bind = osmesa->bind;
  575.       if (all) {
  576.          GLuint  i, n; 
  577.          GLubyte *ptr3 = (GLubyte *) osmesa->buffer;
  578.          /* Clear whole RGB buffer */
  579.          n = osmesa->rowlength * osmesa->height;
  580.          for (i=0;i<n;i++) {
  581.             ptr3[rind] = rval;
  582.             ptr3[gind] = gval;
  583.             ptr3[bind] = bval;
  584.             ptr3 += 3;
  585.          }
  586.       }
  587.       else {
  588.          /* Clear part of RGB buffer */
  589.          GLuint i, j;
  590.          for (i=0;i<height;i++) {
  591.             GLubyte *ptr3 = PIXELADDR3( x, (y+i) );
  592.             for (j=0;j<width;j++) {
  593.                ptr3[rind] = rval;
  594.                ptr3[gind] = gval;
  595.                ptr3[bind] = bval;
  596.                ptr3 += 3;
  597.             }
  598.          }
  599.       }
  600.    }
  601.    else {
  602.       if (all) {
  603.          /* Clear whole RGBA buffer */
  604.          GLuint i, n, *ptr4;
  605.          n = osmesa->rowlength * osmesa->height;
  606.          ptr4 = (GLuint *) osmesa->buffer;
  607.          for (i=0;i<n;i++) {
  608.             *ptr4++ = osmesa->clearpixel;
  609.          }
  610.       }
  611.       else {
  612.          /* Clear part of RGBA buffer */
  613.          GLuint i, j;
  614.          for (i=0;i<height;i++) {
  615.             GLuint *ptr4 = PIXELADDR4( x, (y+i) );
  616.             for (j=0;j<width;j++) {
  617.                *ptr4++ = osmesa->clearpixel;
  618.             }
  619.          }
  620.       }
  621.    }
  622. }
  623.  
  624.  
  625.  
  626. static void set_index( GLcontext *ctx, GLuint index )
  627. {
  628.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  629.    osmesa->pixel = index;
  630. }
  631.  
  632.  
  633.  
  634. static void set_color( GLcontext *ctx,
  635.                        GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  636. {
  637.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  638.    osmesa->pixel = PACK_RGBA( r, g, b, a );
  639. }
  640.  
  641.  
  642.  
  643. static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
  644. {
  645.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  646.    *width = osmesa->width;
  647.    *height = osmesa->height;
  648. }
  649.  
  650.  
  651. /**********************************************************************/
  652. /*****        4 byte RGB and 1 byte CI pixel support funcs        *****/
  653. /**********************************************************************/
  654.  
  655. static void write_color_span( GLcontext *ctx,
  656.                               GLuint n, GLint x, GLint y,
  657.                               const GLubyte red[], const GLubyte green[],
  658.                   const GLubyte blue[], const GLubyte alpha[],
  659.                   const GLubyte mask[] )
  660. {
  661.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  662.    GLuint *ptr4 = PIXELADDR4( x, y );
  663.    GLuint i;
  664.    GLint rshift = osmesa->rshift;
  665.    GLint gshift = osmesa->gshift;
  666.    GLint bshift = osmesa->bshift;
  667.    GLint ashift = osmesa->ashift;
  668.    if (mask) {
  669.       for (i=0;i<n;i++,ptr4++) {
  670.          if (mask[i]) {
  671.             *ptr4 = PACK_RGBA2( red[i], green[i], blue[i], alpha[i] );
  672.          }
  673.       }
  674.    }
  675.    else {
  676.       for (i=0;i<n;i++,ptr4++) {
  677.          *ptr4 = PACK_RGBA2( red[i], green[i], blue[i], alpha[i] );
  678.       }
  679.    }
  680. }
  681.  
  682.  
  683.  
  684. static void write_monocolor_span( GLcontext *ctx,
  685.                                   GLuint n, GLint x, GLint y,
  686.                   const GLubyte mask[] )
  687. {
  688.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  689.    GLuint *ptr4 = PIXELADDR4(x,y);
  690.    GLuint i;
  691.    for (i=0;i<n;i++,ptr4++) {
  692.       if (mask[i]) {
  693.          *ptr4 = osmesa->pixel;
  694.       }
  695.    }
  696. }
  697.  
  698.  
  699.  
  700. static void write_color_pixels( GLcontext *ctx,
  701.                                 GLuint n, const GLint x[], const GLint y[],
  702.                                 const GLubyte red[], const GLubyte green[],
  703.                     const GLubyte blue[], const GLubyte alpha[],
  704.                     const GLubyte mask[] )
  705. {
  706.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  707.    GLuint i;
  708.    GLint rshift = osmesa->rshift;
  709.    GLint gshift = osmesa->gshift;
  710.    GLint bshift = osmesa->bshift;
  711.    GLint ashift = osmesa->ashift;
  712.    for (i=0;i<n;i++) {
  713.       if (mask[i]) {
  714.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  715.          *ptr4 = PACK_RGBA2( red[i], green[i], blue[i], alpha[i] );
  716.       }
  717.    }
  718. }
  719.  
  720.  
  721.  
  722. static void write_monocolor_pixels( GLcontext *ctx,
  723.                                     GLuint n, const GLint x[], const GLint y[],
  724.                     const GLubyte mask[] )
  725. {
  726.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  727.    GLuint i;
  728.    for (i=0;i<n;i++) {
  729.       if (mask[i]) {
  730.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  731.          *ptr4 = osmesa->pixel;
  732.       }
  733.    }
  734. }
  735.  
  736.  
  737.  
  738. static void write_index_span( GLcontext *ctx,
  739.                               GLuint n, GLint x, GLint y, const GLuint index[],
  740.                   const GLubyte mask[] )
  741. {
  742.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  743.    GLubyte *ptr1 = PIXELADDR1(x,y);
  744.    GLuint i;
  745.    for (i=0;i<n;i++,ptr1++) {
  746.       if (mask[i]) {
  747.          *ptr1 = (GLubyte) index[i];
  748.       }
  749.    }
  750. }
  751.  
  752.  
  753.  
  754. static void write_monoindex_span( GLcontext *ctx,
  755.                                   GLuint n, GLint x, GLint y,
  756.                   const GLubyte mask[] )
  757. {
  758.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  759.    GLubyte *ptr1 = PIXELADDR1(x,y);
  760.    GLuint i;
  761.    for (i=0;i<n;i++,ptr1++) {
  762.       if (mask[i]) {
  763.          *ptr1 = (GLubyte) osmesa->pixel;
  764.       }
  765.    }
  766. }
  767.  
  768.  
  769.  
  770. static void write_index_pixels( GLcontext *ctx,
  771.                                 GLuint n, const GLint x[], const GLint y[],
  772.                     const GLuint index[], const GLubyte mask[] )
  773. {
  774.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  775.    GLuint i;
  776.    for (i=0;i<n;i++) {
  777.       if (mask[i]) {
  778.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  779.          *ptr1 = (GLubyte) index[i];
  780.       }
  781.    }
  782. }
  783.  
  784.  
  785.  
  786. static void write_monoindex_pixels( GLcontext *ctx,
  787.                                     GLuint n, const GLint x[], const GLint y[],
  788.                     const GLubyte mask[] )
  789. {
  790.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  791.    GLuint i;
  792.    for (i=0;i<n;i++) {
  793.       if (mask[i]) {
  794.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  795.          *ptr1 = (GLubyte) osmesa->pixel;
  796.       }
  797.    }
  798. }
  799.  
  800.  
  801.  
  802. static void read_index_span( GLcontext *ctx,
  803.                              GLuint n, GLint x, GLint y, GLuint index[] )
  804. {
  805.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  806.    GLuint i;
  807.    GLubyte *ptr1 = PIXELADDR1(x,y);
  808.    for (i=0;i<n;i++,ptr1++) {
  809.       index[i] = (GLuint) *ptr1;
  810.    }
  811. }
  812.  
  813.  
  814. static void read_color_span( GLcontext *ctx,
  815.                              GLuint n, GLint x, GLint y,
  816.                              GLubyte red[], GLubyte green[],
  817.                  GLubyte blue[], GLubyte alpha[] )
  818. {
  819.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  820.    GLuint i;
  821.    GLuint *ptr4 = PIXELADDR4(x,y);
  822.    for (i=0;i<n;i++) {
  823.       GLuint pixel = *ptr4++;
  824.       red[i]   = UNPACK_RED(pixel);
  825.       green[i] = UNPACK_GREEN(pixel);
  826.       blue[i]  = UNPACK_BLUE(pixel);
  827.       alpha[i] = UNPACK_ALPHA(pixel);
  828.    }
  829. }
  830.  
  831.  
  832. static void read_index_pixels( GLcontext *ctx,
  833.                                GLuint n, const GLint x[], const GLint y[],
  834.                    GLuint index[], const GLubyte mask[] )
  835. {
  836.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  837.    GLuint i;
  838.    for (i=0;i<n;i++) {
  839.       if (mask[i] ) {
  840.          GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
  841.          index[i] = (GLuint) *ptr1;
  842.       }
  843.    }
  844. }
  845.  
  846.  
  847. static void read_color_pixels( GLcontext *ctx,
  848.                                GLuint n, const GLint x[], const GLint y[],
  849.                    GLubyte red[], GLubyte green[],
  850.                    GLubyte blue[], GLubyte alpha[],
  851.                                const GLubyte mask[] )
  852. {
  853.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  854.    GLuint i;
  855.    for (i=0;i<n;i++) {
  856.       if (mask[i]) {
  857.          GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
  858.          GLuint pixel = *ptr4;
  859.          red[i]   = UNPACK_RED(pixel);
  860.          green[i] = UNPACK_GREEN(pixel);
  861.          blue[i]  = UNPACK_BLUE(pixel);
  862.          alpha[i] = UNPACK_ALPHA(pixel);
  863.       }
  864.    }
  865. }
  866.  
  867. /**********************************************************************/
  868. /*****                3 byte RGB pixel support funcs              *****/
  869. /**********************************************************************/
  870.  
  871. static void write_color_span3( GLcontext *ctx,
  872.                               GLuint n, GLint x, GLint y,
  873.                               const GLubyte red[], const GLubyte green[],
  874.                   const GLubyte blue[], const GLubyte alpha[],
  875.                   const GLubyte mask[] )
  876. {
  877.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  878.    GLubyte *ptr3 = PIXELADDR3( x, y);
  879.    GLuint i;
  880.    GLint rind = osmesa->rind;
  881.    GLint gind = osmesa->gind;
  882.    GLint bind = osmesa->bind;
  883.    if (mask) {
  884.       for (i=0;i<n;i++,ptr3+=3) {
  885.          if (mask[i]) {
  886.             ptr3[rind] = red[i];
  887.             ptr3[gind] = green[i];
  888.             ptr3[bind] = blue[i];
  889.          }
  890.       }
  891.    }
  892.    else {
  893.       for (i=0;i<n;i++,ptr3+=3) {
  894.          ptr3[rind] = red[i];
  895.          ptr3[gind] = green[i];
  896.          ptr3[bind] = blue[i];
  897.       }
  898.    }
  899. }
  900.  
  901. static void write_monocolor_span3( GLcontext *ctx,
  902.                                   GLuint n, GLint x, GLint y,
  903.                   const GLubyte mask[] )
  904. {
  905.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  906.    
  907.    GLubyte rval = UNPACK_RED(osmesa->pixel);
  908.    GLubyte gval = UNPACK_GREEN(osmesa->pixel);
  909.    GLubyte bval = UNPACK_BLUE(osmesa->pixel);
  910.    GLint   rind = osmesa->rind;
  911.    GLint   gind = osmesa->gind;
  912.    GLint   bind = osmesa->bind;
  913.  
  914.  
  915.    GLubyte *ptr3 = PIXELADDR3( x, y);
  916.    GLuint i;
  917.    for (i=0;i<n;i++,ptr3+=3) {
  918.       if (mask[i]) {
  919.          ptr3[rind] = rval;
  920.          ptr3[gind] = gval;
  921.          ptr3[bind] = bval;
  922.       }
  923.    }
  924. }
  925.  
  926. static void write_color_pixels3( GLcontext *ctx,
  927.                                 GLuint n, const GLint x[], const GLint y[],
  928.                                 const GLubyte red[], const GLubyte green[],
  929.                     const GLubyte blue[], const GLubyte alpha[],
  930.                     const GLubyte mask[] )
  931. {
  932.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  933.    GLuint i;
  934.    GLint rind = osmesa->rind;
  935.    GLint gind = osmesa->gind;
  936.    GLint bind = osmesa->bind;
  937.  
  938.    for (i=0;i<n;i++) {
  939.       if (mask[i]) {
  940.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  941.          ptr3[rind] = red[i];
  942.          ptr3[gind] = green[i];
  943.          ptr3[bind] = blue[i];
  944.       }
  945.    }
  946. }
  947.  
  948. static void write_monocolor_pixels3( GLcontext *ctx,
  949.                                     GLuint n, const GLint x[], const GLint y[],
  950.                     const GLubyte mask[] )
  951. {
  952.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  953.    GLuint i;
  954.    GLint rind = osmesa->rind;
  955.    GLint gind = osmesa->gind;
  956.    GLint bind = osmesa->bind;
  957.    GLubyte rval = UNPACK_RED(osmesa->pixel);
  958.    GLubyte gval = UNPACK_GREEN(osmesa->pixel);
  959.    GLubyte bval = UNPACK_BLUE(osmesa->pixel);
  960.    for (i=0;i<n;i++) {
  961.       if (mask[i]) {
  962.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  963.          ptr3[rind] = rval;
  964.          ptr3[gind] = gval;
  965.          ptr3[bind] = bval;
  966.       }
  967.    }
  968. }
  969.  
  970. static void read_color_span3( GLcontext *ctx,
  971.                              GLuint n, GLint x, GLint y,
  972.                              GLubyte red[], GLubyte green[],
  973.                  GLubyte blue[], GLubyte alpha[] )
  974. {
  975.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  976.    GLuint i;
  977.    GLint rind = osmesa->rind;
  978.    GLint gind = osmesa->gind;
  979.    GLint bind = osmesa->bind;
  980.    GLubyte *ptr3 = PIXELADDR3( x, y);
  981.    for (i=0;i<n;i++,ptr3+=3) {
  982.       red[i]   = ptr3[rind];
  983.       green[i] = ptr3[gind];
  984.       blue[i]  = ptr3[bind];
  985.       alpha[i] = 0;
  986.    }
  987. }
  988.  
  989. static void read_color_pixels3( GLcontext *ctx,
  990.                                GLuint n, const GLint x[], const GLint y[],
  991.                    GLubyte red[], GLubyte green[],
  992.                    GLubyte blue[], GLubyte alpha[],
  993.                                const GLubyte mask[] )
  994. {
  995.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  996.    GLuint i;
  997.    GLint rind = osmesa->rind;
  998.    GLint gind = osmesa->gind;
  999.    GLint bind = osmesa->bind;
  1000.    for (i=0;i<n;i++) {
  1001.       if (mask[i]) {
  1002.          GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
  1003.          red[i]   = ptr3[rind];
  1004.          green[i] = ptr3[gind];
  1005.          blue[i]  = ptr3[bind];
  1006.          alpha[i] = 0;
  1007.       }
  1008.    }
  1009. }
  1010.  
  1011.  
  1012. /**********************************************************************/
  1013. /*****                   Optimized line rendering                 *****/
  1014. /**********************************************************************/
  1015.  
  1016. /*
  1017.  * Despite being clipped to the view volume, the line's window coordinates
  1018.  * may just lie outside the window bounds.  That is, if the legal window
  1019.  * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
  1020.  * These quick and dirty macros take care of that possibility.
  1021.  */
  1022.  
  1023. #define WINCLIP_X(X1,X2)        \
  1024.    {                    \
  1025.       GLint w = ctx->Buffer->Width;    \
  1026.       if ((X1==w) | (X2==w)) {        \
  1027.          if ((X1==w) & (X2==w))  return;\
  1028.          X1 -= (X1==w);   X2 -= (X2==w);\
  1029.       }                    \
  1030.    }
  1031.  
  1032. #define WINCLIP_Y(Y1,Y2)        \
  1033.    {                    \
  1034.       GLint h = ctx->Buffer->Height;    \
  1035.       if ((Y1==h) | (Y2==h)) {        \
  1036.          if ((Y1==h) & (Y2==h))  return;\
  1037.          Y1 -= (Y1==h);   Y2 -= (Y2==h);\
  1038.       }                    \
  1039.    }
  1040.  
  1041. /*
  1042.  * Draw a flat-shaded, RGB line into an osmesa buffer.
  1043.  */
  1044. static void flat_color_line( GLcontext *ctx,
  1045.                                  GLuint v0, GLuint v1, GLuint pv )
  1046. {
  1047.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1048.    struct vertex_buffer *VB = ctx->VB;
  1049.    GLint x1 = (GLint) VB->Win[v0][0], y1 = (GLint) VB->Win[v0][1];
  1050.    GLint x2 = (GLint) VB->Win[v1][0], y2 = (GLint) VB->Win[v1][1];
  1051.    unsigned long pixel = PACK_RGBA( VB->Color[pv][0], VB->Color[pv][1],
  1052.                                    VB->Color[pv][2], 0 );
  1053.    WINCLIP_X(x1,x2);
  1054.    WINCLIP_Y(y1,y2);
  1055.  
  1056. #define BRESENHAM_PLOT(X,Y)                    \
  1057.    { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
  1058.  
  1059.    BRESENHAM( x1, y1, x2, y2 );
  1060.  
  1061. #undef BRESENHAM_PLOT
  1062. }
  1063.  
  1064. /*
  1065.  * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
  1066.  */
  1067. static void flat_color_z_line( GLcontext *ctx,
  1068.                                    GLuint v0, GLuint v1, GLuint pv )
  1069. {
  1070.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1071.    struct vertex_buffer *VB = ctx->VB;
  1072.    GLint x1 = (GLint) VB->Win[v0][0], x2 = (GLint) VB->Win[v1][0];
  1073.    GLint y1 = (GLint) VB->Win[v0][1], y2 = (GLint) VB->Win[v1][1];
  1074.    GLint z1 = (GLint) (VB->Win[v0][2] + ctx->LineZoffset);
  1075.    GLint z2 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset);
  1076.    unsigned long pixel = PACK_RGBA( VB->Color[pv][0], VB->Color[pv][1],
  1077.                                    VB->Color[pv][2], 0 );
  1078.  
  1079.    WINCLIP_X(x1,x2);
  1080.    WINCLIP_Y(y1,y2);
  1081.  
  1082. #define BRESENHAM_PLOT(X,Y,Z,ZBUF)        \
  1083.     if (Z < *ZBUF) {            \
  1084.           { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; } \
  1085.        *ZBUF = Z;                \
  1086.     }
  1087.  
  1088.    BRESENHAM_Z( ctx, x1, y1, z1, x2, y2, z2 );
  1089.  
  1090. #undef BRESENHAM_PLOT
  1091. }
  1092.  
  1093. /*
  1094.  * Analyze context state to see if we can provide a fast line drawing
  1095.  * function, like those in lines.c.  Otherwise, return NULL.
  1096.  */
  1097. static line_func choose_line_function( GLcontext *ctx )
  1098. {
  1099.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1100.    
  1101.    if (ctx->Line.SmoothFlag)              return NULL;
  1102.    if (ctx->Texture.Enabled)              return NULL;
  1103.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  1104.  
  1105.    if (ctx->RasterMask==DEPTH_BIT
  1106.        && ctx->Depth.Func==GL_LESS
  1107.        && ctx->Depth.Mask==GL_TRUE
  1108.        && ctx->Line.Width==1.0F
  1109.        && ctx->Line.StippleFlag==GL_FALSE) {
  1110.        switch(osmesa->format) {
  1111.                case OSMESA_RGBA:
  1112.                case OSMESA_BGRA:
  1113.                case OSMESA_ARGB:
  1114.                    return flat_color_z_line;
  1115.                    break;
  1116.                default:
  1117.                    return NULL;
  1118.                    break;
  1119.        }
  1120.    }
  1121.    if (ctx->RasterMask==0
  1122.        && ctx->Line.Width==1.0F
  1123.        && ctx->Line.StippleFlag==GL_FALSE) {
  1124.        switch(osmesa->format) {
  1125.                case OSMESA_RGBA:
  1126.                case OSMESA_BGRA:
  1127.                case OSMESA_ARGB:
  1128.                    return flat_color_line;
  1129.                    break;
  1130.                default:
  1131.                    return NULL;
  1132.                    break;
  1133.        }
  1134.    }
  1135.    return NULL;
  1136. }
  1137.  
  1138. /**********************************************************************/
  1139. /*****                 Optimized triangle rendering               *****/
  1140. /**********************************************************************/
  1141.  
  1142.  
  1143. /*
  1144.  * Smooth-shaded, z-less triangle, RGBA color.
  1145.  */
  1146. static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1147.                                      GLuint v2, GLuint pv )
  1148. {
  1149.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1150.    GLint rshift = osmesa->rshift;
  1151.    GLint gshift = osmesa->gshift;
  1152.    GLint bshift = osmesa->bshift;
  1153.    GLint ashift = osmesa->ashift;
  1154. #define INTERP_Z 1
  1155. #define INTERP_RGB 1
  1156. #define INTERP_ALPHA 1
  1157. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  1158. {                                \
  1159.    GLint i, len = RIGHT-LEFT;                    \
  1160.    GLuint *img = PIXELADDR4(LEFT,Y);                   \
  1161.    for (i=0;i<len;i++,img++) {                    \
  1162.       GLdepth z = FixedToDepth(ffz);                \
  1163.       if (z < zRow[i]) {                    \
  1164.          *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg),    \
  1165.                     FixedToInt(ffb), FixedToInt(ffa) );    \
  1166.          zRow[i] = z;                        \
  1167.       }                                \
  1168.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
  1169.       ffz += fdzdx;                        \
  1170.    }                                \
  1171. }
  1172. #include "tritemp.h"
  1173. }
  1174.  
  1175.  
  1176.  
  1177.  
  1178. /*
  1179.  * Flat-shaded, z-less triangle, RGBA color.
  1180.  */
  1181. static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1182.                                    GLuint v2, GLuint pv )
  1183. {
  1184.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1185. #define INTERP_Z 1
  1186. #define SETUP_CODE            \
  1187.    GLubyte r = VB->Color[pv][0];    \
  1188.    GLubyte g = VB->Color[pv][1];    \
  1189.    GLubyte b = VB->Color[pv][2];    \
  1190.    GLubyte a = VB->Color[pv][3];    \
  1191.    GLuint pixel = PACK_RGBA(r,g,b,a);
  1192.  
  1193. #define INNER_LOOP( LEFT, RIGHT, Y )    \
  1194. {                    \
  1195.    GLint i, len = RIGHT-LEFT;        \
  1196.    GLuint *img = PIXELADDR4(LEFT,Y);       \
  1197.    for (i=0;i<len;i++,img++) {        \
  1198.       GLdepth z = FixedToDepth(ffz);    \
  1199.       if (z < zRow[i]) {        \
  1200.          *img = pixel;            \
  1201.          zRow[i] = z;            \
  1202.       }                    \
  1203.       ffz += fdzdx;            \
  1204.    }                    \
  1205. }
  1206. #include "tritemp.h"
  1207. }
  1208.  
  1209.  
  1210.  
  1211. /*
  1212.  * Return pointer to an accelerated triangle function if possible.
  1213.  */
  1214. static triangle_func choose_triangle_function( GLcontext *ctx )
  1215. {
  1216.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1217.  
  1218.    if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) return NULL;
  1219.    
  1220.    if (ctx->Polygon.SmoothFlag)     return NULL;
  1221.    if (ctx->Polygon.StippleFlag)    return NULL;
  1222.    if (ctx->Texture.Enabled)        return NULL;
  1223.  
  1224.    if (ctx->RasterMask==DEPTH_BIT
  1225.        && ctx->Depth.Func==GL_LESS
  1226.        && ctx->Depth.Mask==GL_TRUE
  1227.        && osmesa->format!=OSMESA_COLOR_INDEX) {
  1228.       if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1229.          return smooth_color_z_triangle;
  1230.       }
  1231.       else {
  1232.          return flat_color_z_triangle;
  1233.       }
  1234.    }
  1235.    return NULL;
  1236. }
  1237.  
  1238.  
  1239.  
  1240. static void osmesa_setup_DD_pointers( GLcontext *ctx )
  1241. {
  1242.    OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
  1243.    
  1244.    ctx->Driver.UpdateState = osmesa_setup_DD_pointers;
  1245.  
  1246.    ctx->Driver.SetBuffer = set_buffer;
  1247.    ctx->Driver.Color = set_color;
  1248.    ctx->Driver.Index = set_index;
  1249.    ctx->Driver.ClearIndex = clear_index;
  1250.    ctx->Driver.ClearColor = clear_color;
  1251.    ctx->Driver.Clear = clear;
  1252.  
  1253.    ctx->Driver.GetBufferSize = buffer_size;
  1254.  
  1255.    ctx->Driver.PointsFunc = NULL;
  1256.    ctx->Driver.LineFunc = choose_line_function( ctx );
  1257.    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1258.    
  1259.    ctx->Driver.WriteColorSpan = write_color_span;
  1260.    ctx->Driver.WriteColorPixels = write_color_pixels;
  1261.    ctx->Driver.WriteIndexSpan = write_index_span;
  1262.    ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
  1263.    ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
  1264.    ctx->Driver.WriteIndexPixels = write_index_pixels;
  1265.    ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
  1266.    ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
  1267.  
  1268.    ctx->Driver.ReadColorSpan = read_color_span;
  1269.    ctx->Driver.ReadIndexSpan = read_index_span;
  1270.    ctx->Driver.ReadColorPixels = read_color_pixels;
  1271.    ctx->Driver.ReadIndexPixels = read_index_pixels;
  1272.    
  1273.    if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) {
  1274.       ctx->Driver.WriteColorSpan = write_color_span3;
  1275.       ctx->Driver.WriteColorPixels = write_color_pixels3;
  1276.       ctx->Driver.WriteMonocolorSpan = write_monocolor_span3;
  1277.       ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels3;
  1278.  
  1279.       ctx->Driver.ReadColorSpan = read_color_span3;
  1280.       ctx->Driver.ReadColorPixels = read_color_pixels3;
  1281.    }
  1282.  
  1283. }
  1284.